package com.nlscan.ncomgateway.core.newland.common

import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.NhubManager
import android.text.TextUtils
import android.util.Log
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.nlscan.android.scan.ScanSettings
import com.nlscan.ble.util.NLogUtil

/**
 * 1. 修改缓存值
 */
object NlsVariateHelper {

    private const val TAG = "NlsVariateHelper"
    private const val DEBUG_LOG = true

    //----------------------- NTS相关 BEGIN ---------------------------//

    fun initNtsParam(context: Context?) {
        //[bugFix] java.lang.NoClassDefFoundError: Failed resolution of: Landroid/os/NhubManager;
        val service = context?.getSystemService(NlsConst.NLS_DATA_HUB_SERVICE)
        if (service != null) {
            NlsVariate.nhubManager = service as? NhubManager?
            NlsVariate.supportNts = (NlsVariate.nhubManager != null
                    && isAppPlatform(context))
        }
    }

    private fun isAppPlatform(context: Context?): Boolean {
        return if (context == null) {
            false
        } else {
            context.applicationContext.packageManager.checkPermission(
                // android.permission.WRITE_SECURE_SETTINGS 需要在AndroidManifest中声明
                "android.permission.WRITE_SECURE_SETTINGS",
                context.applicationContext.packageName
            ) == PackageManager.PERMISSION_GRANTED
        }
    }

    fun updateNlsProfileFromIntent(intent: Intent?) {
        if (!isSupportNts()) return
        NlsVariate.profileName =
            intent?.getStringExtra(NlsConst.EXTRA_PROFILE_NAME) ?: NlsConst.DEFAULT_PROFILE_NAME
        Log.i(TAG, "updateNlsProfileFromIntent profile: ${NlsVariate.profileName}")
        updateSettings()
        updateOcrBroadcastExtraMap()
    }

    /**
     * 从 NhubService 系统服务更新 setting map
     * -- param 更新
     * -- ProfileName 变更
     */
    fun updateSettings(): HashMap<String, String?>? {
        val param = NlsVariate.nhubManager?.settingsOfAllProfile?.get(getProfileName())
        param?.let {
            NlsVariate.settingsMap = (it as? HashMap<String, String?>) ?: null
        }
        if (DEBUG_LOG) {
            NLogUtil.d(
                "updateSettings profile: ${getProfileName()}," +
                        " settingsMap is null? ${NlsVariate.settingsMap == null}"
            )
            NlsVariate.settingsMap?.let {
                for (entry in it.entries) {
                    NLogUtil.d("NhubSettings key: ${entry.key}, value: ${entry.value}")
                }
            }
        }
        //更新
        updateOcrBroadcastExtraMap()

        return NlsVariate.settingsMap
    }

    private fun updateOcrBroadcastExtraMap() : HashMap<String, String?>? {
        val jsonString = NlsVariate.settingsMap?.get(NlsConst.NTS_OCR_BROADCAST_EXTRA_MAP)
            ?:"{}"

        val gson = Gson()
        val type = object : TypeToken<HashMap<String,String?>>(){}.type
        val map : HashMap<String, String?> = gson.fromJson(jsonString, type)

        NlsVariate.ocrBroadcastExtraMap = map

        if (DEBUG_LOG) {
            NLogUtil.d(
                "updateOcrBroadcastExtraMap profile: ${getProfileName()}," +
                        " ocrBroadcastExtraMap is null? ${NlsVariate.ocrBroadcastExtraMap == null}" +
                        ", size: ${NlsVariate.ocrBroadcastExtraMap?.size}"
            )
            NlsVariate.ocrBroadcastExtraMap?.let {
                for (entry in it.entries) {
                    NLogUtil.d("ocrBroadcastExtraMap key: ${entry.key}, value: ${entry.value}")
                }
            }
        }
        return NlsVariate.ocrBroadcastExtraMap
    }


    fun getOutputMode(): Int {
        return NlsVariate.settingsMap?.get(NlsConst.NTS_OUTPUT_MODE)?.toInt()
            ?: ScanSettings.Global.VALUE_OUT_PUT_MODE_BROADCAST
    }

    fun setOutputMode(mode: Int) {
        NlsVariate.settingsMap?.run {
            set(NlsConst.NTS_OUTPUT_MODE, mode.toString())
        }
    }

    fun getBroadcastOutputAction(): String {
        return NlsVariate.settingsMap?.get(NlsConst.NTS_BROADCAST_OUTPUT_ACTION)
            ?: ""
    }

    fun setBroadcastOutputAction(value: String) {
        getSettingsMap()?.run {
            set(NlsConst.NTS_BROADCAST_OUTPUT_ACTION, value)
        }
    }

    fun getBroadcastOutputExtraResult(): String {
        return NlsVariate.settingsMap?.get(NlsConst.NTS_BROADCAST_OUTPUT_EXTRA_KEY_RESULT_1)
            ?: ""
    }

    fun setBroadcastOutputExtraResult(value: String) {
        NlsVariate.settingsMap?.run {
            set(NlsConst.NTS_BROADCAST_OUTPUT_EXTRA_KEY_RESULT_1, value)
        }
    }

    fun getBroadcastOutputExtraResult2(): String {
        return getSettingsMap()?.get(NlsConst.NTS_BROADCAST_OUTPUT_EXTRA_KEY_RESULT_2)
            ?: ""
    }

    fun setBroadcastOutputExtraResult2(value: String) {
        getSettingsMap()?.run {
            set(NlsConst.NTS_BROADCAST_OUTPUT_EXTRA_KEY_RESULT_2, value)
        }
    }

    fun getBroadcastOutputExtraBarcodeType(): String {
        return getSettingsMap()?.get(NlsConst.NTS_BROADCAST_OUTPUT_EXTRA__KEY_BARCODE_TYPE)
            ?: ""
    }

    fun setBroadcastOutputExtraBarcodeType(value: String) {
        getSettingsMap()?.run {
            set(NlsConst.NTS_BROADCAST_OUTPUT_EXTRA__KEY_BARCODE_TYPE, value)
        }
    }

    fun getBroadcastOutputExtraBarcodeTypeName(): String {
        return getSettingsMap()?.get(NlsConst.NTS_BROADCAST_OUTPUT_EXTRA__KEY_BARCODE_TYPE_NAME)
            ?: ""
    }

    fun setBroadcastOutputExtraBarcodeTypeName(value: String) {
        getSettingsMap()?.run {
            set(NlsConst.NTS_BROADCAST_OUTPUT_EXTRA__KEY_BARCODE_TYPE_NAME, value)
        }
    }

    /**
     * OCR值跟服务器约定，未修改服务器传值为null，即使用OCR 默认值
     * [bugFix] key: ocrBroadcastAction, value: null
     */
    fun getOcrBroadcastAction(): String {
        val value = getSettingsMap()?.get(NlsConst.NTS_OCR_BROADCAST_ACTION)
            ?: NlsConfig.DEFAULT_OCR_SEND_RESULT_ACTION
        return if ("null" == value) NlsConfig.DEFAULT_OCR_SEND_RESULT_ACTION
        else value
    }

    fun setOcrBroadcastAction(value: String) {
        getSettingsMap()?.run {
            set(NlsConst.NTS_OCR_BROADCAST_ACTION, value)
        }

        //debug 同步给 ocrMap中设置
//        getOcrBroadcastExtraMap()?.run {
//            set(NlsConst.NTS_OCR_BROADCAST_ACTION, value)
//        }

    }

    /**
     * OCR值跟服务器约定，未修改服务器传值为null，即使用OCR 默认值
     * todo 待确认，是否使用该值
     *
     */
    fun getOcrBroadcastResultParamName(): String {
        val value = getSettingsMap()?.get(NlsConst.NTS_OCR_BROADCAST_RESULT_PARAM_NAME)
            ?: NlsConfig.DEFAULT_OCR_SEND_RESULT_EXTRA_REGEX_RESULT
        return if ("null" == value) NlsConfig.DEFAULT_OCR_SEND_RESULT_EXTRA_REGEX_RESULT
        else value
    }

    fun setOcrBroadcastResultParamName(value: String) {
        getSettingsMap()?.run {
            set(NlsConst.NTS_OCR_BROADCAST_RESULT_PARAM_NAME, value)
        }
    }

    fun getOcrBroadcastExtraConfidence(): String {
        val value = getOcrBroadcastExtraMap()?.get(NlsConst.NTS_OCR_BROADCAST_EXTRA_CONFIDENCE)
            ?: ""
        return if (TextUtils.isEmpty(value) || "null" == value)
            NlsConfig.DEFAULT_OCR_SEND_RESULT_EXTRA_CONFIDENCE
        else value
    }

    fun setOcrBroadcastExtraConfidence(value: String) {
        //[bugFix] map使用错误
        //getSettingsMap()?.run {
        getOcrBroadcastExtraMap()?.run {
            set(NlsConst.NTS_OCR_BROADCAST_EXTRA_CONFIDENCE, value)
        }
    }

    fun getOcrBroadcastExtraAllConfidence(): String {
        val value = getOcrBroadcastExtraMap()?.get(NlsConst.NTS_OCR_BROADCAST_EXTRA_ALL_CONFIDENCE)
            ?: ""
        return if (TextUtils.isEmpty(value) || "null" == value)
            NlsConfig.DEFAULT_OCR_SEND_RESULT_EXTRA_ALL_CONFIDENCE
        else value
    }

    fun setOcrBroadcastExtraAllConfidence(value: String) {
        getOcrBroadcastExtraMap()?.run {
            set(NlsConst.NTS_OCR_BROADCAST_EXTRA_ALL_CONFIDENCE, value)
        }
    }

    fun getOcrBroadcastExtraCoordinate(): String {
        val value = getOcrBroadcastExtraMap()?.get(NlsConst.NTS_OCR_BROADCAST_EXTRA_COORDINATE)
            ?: ""
        return if (TextUtils.isEmpty(value) || "null" == value)
            NlsConfig.DEFAULT_OCR_SEND_RESULT_EXTRA_COORDINATE
        else value
    }

    fun setOcrBroadcastExtraCoordinate(value: String) {
        getOcrBroadcastExtraMap()?.run {
            set(NlsConst.NTS_OCR_BROADCAST_EXTRA_COORDINATE, value)
        }
    }

    fun getOcrBroadcastExtraOriginalData(): String {
        val value = getOcrBroadcastExtraMap()?.get(NlsConst.NTS_OCR_BROADCAST_EXTRA_ORIGINAL_DATA)
            ?: ""
        return if (TextUtils.isEmpty(value) || "null" == value)
            NlsConfig.DEFAULT_OCR_SEND_RESULT_EXTRA_ORIGINAL_DATA
        else value
    }

    fun setOcrBroadcastExtraOriginalData(value: String) {
        getOcrBroadcastExtraMap()?.run {
            set(NlsConst.NTS_OCR_BROADCAST_EXTRA_ORIGINAL_DATA, value)
        }
    }

    fun getOcrBroadcastExtraImage(): String {
        val value = getOcrBroadcastExtraMap()?.get(NlsConst.NTS_OCR_BROADCAST_EXTRA_IMAGE)
            ?: ""
        return if (TextUtils.isEmpty(value) || "null" == value)
            NlsConfig.DEFAULT_OCR_SEND_RESULT_EXTRA_IMAGE
        else value
    }

    fun setOcrBroadcastExtraImage(value: String) {
        getOcrBroadcastExtraMap()?.run {
            set(NlsConst.NTS_OCR_BROADCAST_EXTRA_IMAGE, value)
        }
    }

    fun setIndicateSoundEnable(enable: Boolean) {
        getSettingsMap()?.run {
            set(NlsConst.NTS_SOUND_ENABLE, enable.toString())
        }
    }

    fun getIndicateVibrateEnable(): Boolean {
        return getSettingsMap()?.get(NlsConst.NTS_VIBRATE_ENABLE)?.toBoolean()
            ?: false
    }

    fun setIndicateVibrateEnable(enable: Boolean) {
        getSettingsMap()?.run {
            set(NlsConst.NTS_VIBRATE_ENABLE, enable.toString())
        }
    }

    fun getIndicateLedEnable(): Boolean {
        return getSettingsMap()?.get(NlsConst.NTS_LED_ENABLE)?.toBoolean()
            ?: false
    }

    fun setIndicateLedEnable(enable: Boolean) {
        getSettingsMap()?.run {
            set(NlsConst.NTS_LED_ENABLE, enable.toString())
        }
    }

    /**
     * [bugFix]修复返回值为null的情况
     */
    fun getPrefix(): String {
        val value = getSettingsMap()?.get(NlsConst.NTS_PREFIX) ?: ""
        return if ("null" == value) "" else value
    }

    fun setPrefix(value: String) {
        getSettingsMap()?.run {
            set(NlsConst.NTS_PREFIX, value)
        }
    }

    fun getPrefixEnable(): Boolean {
        return getSettingsMap()?.get(NlsConst.NTS_PREFIX_ENABLE)?.toBoolean()
            ?: false
    }

    fun setPrefixEnable(enable: Boolean) {
        getSettingsMap()?.run {
            set(NlsConst.NTS_PREFIX_ENABLE, enable.toString())
        }
    }

    fun getSuffix(): String {
        val value = getSettingsMap()?.get(NlsConst.NTS_SUFFIX) ?: ""
        return if ("null" == value) "" else value
    }

    fun setSuffix(value: String) {
        getSettingsMap()?.run {
            set(NlsConst.NTS_SUFFIX, value)
        }
    }

    fun getSuffixEnable(): Boolean {
        return getSettingsMap()?.get(NlsConst.NTS_SUFFIX_ENABLE)?.toBoolean()
            ?: false
    }

    fun setSuffixEnable(enable: Boolean) {
        getSettingsMap()?.run {
            set(NlsConst.NTS_SUFFIX_ENABLE, enable.toString())
        }
    }

    private fun isSupportNts(): Boolean = NlsVariate.supportNts

    private fun getNhubManager() = NlsVariate.nhubManager

    private fun getProfileName() = NlsVariate.profileName

    private fun getSettingsMap(): HashMap<String, String?>? =
        NlsVariate.settingsMap

    private fun getOcrBroadcastExtraMap(): HashMap<String, String?>? =
        NlsVariate.ocrBroadcastExtraMap

    //----------------------- NTS相关 END ---------------------------//

}